from rest_framework import status
from rest_framework.decorators import api_view, permission_classes, authentication_classes
from rest_framework.permissions import AllowAny, IsAuthenticated
from rest_framework.authentication import TokenAuthentication
from rest_framework.response import Response
from django.db.models import Q, Count
from django.core.paginator import Paginator
from django.utils import timezone
from datetime import datetime, timedelta
from .models import Article, ArticleImage, Like
from .serializers import (
    ArticleListSerializer, ArticleDetailSerializer, 
    ArticleCreateSerializer, ArticleUpdateSerializer, BoardSerializer
)
from apps.boards.models import ParentBoard, Board, BoardPostPermission
from apps.users.models import User, UserMessage
from utils.oss_utils import get_oss_uploader
from utils.response import success_response, error_response
import logging

logger = logging.getLogger(__name__)


@api_view(['POST'])
@permission_classes([AllowAny])
def get_home_list(request):
    """获取首页文章列表（每个板块点赞数最多的四篇文章）"""
    try:
        # 获取所有父板块
        parent_boards = ParentBoard.objects.all()
        
        result_list = []
        
        for p_board in parent_boards:
            # Notice板块特殊处理：返回所有top_type为True的文章
            if p_board.board_name == "Notice":
                top_articles = Article.objects.filter(
                    top_type=True
                ).order_by('-good_count', '-post_time')
            else:
                # 其他板块：获取该父板块下点赞数最多的4篇文章
                top_articles = Article.objects.filter(
                    p_board=p_board
                ).order_by('-good_count', '-post_time')[:4]
            
            articles_data = []
            for article in top_articles:
                articles_data.append({
                    "articleId": article.article_id,
                    "title": article.title
                })
            
            # 无论是否有文章，都添加板块信息
            result_list.append({
                "pBoardId": p_board.p_board_id,
                "pBoardName": p_board.board_name,
                "articles": articles_data
            })
        
        return success_response({
            "totalCount": len(result_list),
            "list": result_list
        })
        
    except Exception as e:
        return error_response(message=str(e))

@api_view(['POST'])
@permission_classes([AllowAny])
def get_article_list(request):
    """获取文章列表"""
    try:
        page_no = int(request.data.get('pageNo', 1))
        page_size = int(request.data.get('pageSize', 15))

        queryset = ArticleListSerializer.filter_queryset(request.data)

        paginator = Paginator(queryset, page_size)
        page_obj = paginator.get_page(page_no)

        serializer = ArticleListSerializer(
            page_obj.object_list, many=True, context={'request': request}
        )

        return success_response({
            'totalCount': paginator.count,
            'pageSize': page_size,
            'pageNo': page_no,
            'pageTotal': paginator.num_pages,
            'list': serializer.data
        })

    except Exception as e:
        return error_response(message=str(e))


@api_view(['POST'])
@permission_classes([AllowAny])
def get_article_detail(request):
    """获取文章详情"""
    article_id = request.data.get('articleId')
    if not article_id:
        return error_response(message="Article ID cannot be empty")

    article = ArticleDetailSerializer.get_article_detail(article_id)
    if not article:
        return error_response(message="The article does not exist.")

    serializer = ArticleDetailSerializer(article, context={'request': request})
    return success_response(data=serializer.data)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def do_like_article(request):
    """点赞文章"""
    article_id = request.data.get('articleId')

    if not article_id:
        return error_response(message="Article ID cannot be empty")

    try:
        article = Article.objects.get(article_id=article_id)

        # 检查是否已点赞
        like_obj, created = Like.objects.get_or_create(
            like_type=0,
            object_id=article_id,
            user=request.user,
            defaults={'author_user_id': str(article.user.user_id)}
        )

        if created:
            # 新增点赞，增加点赞数
            article.good_count += 1
            article.save()

            # 给文章作者发送点赞通知（不给自己发通知）
            if article.user != request.user:
                UserMessage.objects.create(
                    received_user_id=str(article.user.user_id),
                    article_id=str(article_id),
                    article_title=article.title,
                    comment_id=None,
                    send_user_id=str(request.user.user_id),
                    send_nick_name=request.user.nickname,
                    message_type=3,
                    message_content=f"{request.user.nickname} liked your article",
                    status=0
                )

            return success_response(data={"isLiked": True})
        else:
            # 已存在，取消点赞
            like_obj.delete()
            article.good_count = max(0, article.good_count - 1)
            article.save()

            return success_response(data={"isLiked": False})
    except Article.DoesNotExist:
        return error_response(message="The article does not exist.")


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def publish_article(request):
    """发布文章"""
    serializer = ArticleCreateSerializer(data=request.data, context={'request': request})
    if serializer.is_valid():
        article = serializer.save()
        return success_response(data=article.article_id, message="Published successfully")
    return error_response(message=serializer.errors)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def edit_article(request):
    """修改文章"""
    serializer = ArticleUpdateSerializer(data=request.data, context={'request': request}, partial=True)
    if serializer.is_valid():
        article = serializer.save()
        return success_response(data=article.article_id, message="Modified successfully")

    return error_response(message=serializer.errors)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def delete_article(request):
    """删除文章"""
    try:
        article_id = request.data.get('articleId')
        if not article_id:
            return error_response(message="Article ID cannot be empty")

        try:
            article = Article.objects.get(article_id=article_id)
        except Article.DoesNotExist:
            return error_response(message="The article does not exist")

        # 只有文章作者可以删除
        if article.user.user_id != request.user.user_id:
            return error_response(message="No permission to delete this article")

        # 删除文章的点赞
        Like.objects.filter(like_type=0, object_id=article_id).delete()

        # 删除评论的点赞
        comment_ids = list(article.comments.values_list('comment_id', flat=True))

        if comment_ids:
            Like.objects.filter(like_type=1, object_id__in=comment_ids).delete()

        article.delete()

        return success_response(message="Article deleted successfully")

    except Exception as e:
        logger.error(f"Delete article error: {str(e)}")
        return error_response(message="Failed to delete article")


@api_view(['POST'])
@permission_classes([AllowAny])
def search_articles(request):
    """搜索文章"""
    keyword = request.data.get('keyword')
    search_type = int(request.data.get('searchType', 0))
    page_no = int(request.data.get('pageNo', 1))
    page_size = int(request.data.get('pageSize', 15))

    if not keyword:
        return error_response(message="Keywords cannot be empty")

    # 搜索条件
    if search_type == 0:  # 标题
        queryset = Article.objects.filter(title__icontains=keyword)
    elif search_type == 1:  # 用户名
        queryset = Article.objects.filter(user__nickname__icontains=keyword)
    else:
        queryset = Article.objects.filter(
            Q(title__icontains=keyword) | Q(user__nickname__icontains=keyword)
        )

    queryset = queryset.order_by('-post_time')

    paginator = Paginator(queryset, page_size)
    page_obj = paginator.get_page(page_no)

    serializer = ArticleListSerializer(page_obj.object_list, many=True)

    return success_response({
        'totalCount': paginator.count,
        'pageSize': page_size,
        'pageNo': page_no,
        'pageTotal': paginator.num_pages,
        'list': serializer.data
    })


@api_view(['POST'])
@permission_classes([AllowAny])
def get_boards(request):
    """获取板块信息"""
    p_board_id = request.data.get('pBoardId')
    board_id = request.data.get('boardId')

    if p_board_id or board_id:
        # 返回特定板块信息
        queryset = ParentBoard.objects.all()
        if p_board_id:
            queryset = queryset.filter(p_board_id=p_board_id)
    else:
        # 返回所有板块信息
        queryset = ParentBoard.objects.all().prefetch_related('children')

    serializer = BoardSerializer(queryset, many=True)
    return success_response(serializer.data)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def upload_image(request):
    """上传图片到阿里云OSS"""
    try:
        # 检查是否有上传的文件
        if 'image' not in request.FILES:
            return error_response(message="Please select the image to upload")

        image_file = request.FILES['image']

        allowed_types = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp']
        if image_file.content_type not in allowed_types:
            return error_response(message="Unsupported image format")

        max_size = 10 * 1024 * 1024  # 10MB
        if image_file.size > max_size:
            return error_response(message="The image size cannot exceed 10MB")

        if not image_file.name:
            return error_response(message="The file name cannot be empty")

        uploader = get_oss_uploader()
        if not uploader:
            logger.error("OSS uploader initialization failed")
            return error_response(message="The image upload service is temporarily unavailable", code=500)

        image_url = uploader.upload_file(image_file, folder='articles')

        if image_url:

            logger.info(f"User {request.user.user_id} uploaded image successfully: {image_url}")
            return success_response({
                'imageUrl': image_url,
                'fileName': image_file.name,
                'fileSize': image_file.size
            }, message="Picture uploaded successfully")
        else:
            logger.error(f"User {request.user.user_id} image upload failed")
            return error_response(message="Picture upload failed, please try again", code=500)

    except Exception as e:
        logger.error(f"Image upload exception: {e}")
        return error_response(message="Picture upload exception, please try again", code=500)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def delete_image(request):
    """
    删除图片
    """
    try:
        image_url = request.data.get('image_url')

        if not image_url:
            return error_response("Image URL cannot be empty")

        oss_uploader = get_oss_uploader()
        if not oss_uploader:
            return error_response("OSS service initialization failed")

        success = oss_uploader.delete_file(image_url)

        if success:

            logger.info(f"User {request.user.username} deleted image successfully: {image_url}")
            return success_response("Image deleted successfully")
        else:
            return error_response("Image deletion failed")

    except Exception as e:
        logger.error(f"Failed to delete image: {e}")
        return error_response("Delete failed, please try again")


@api_view(['POST'])
@permission_classes([AllowAny])
def get_daily_top_articles(request):
    """获取当日点赞数最多的5篇文章"""
    try:
        today = timezone.now().date()
        today_start = datetime.combine(today, datetime.min.time())
        today_end = datetime.combine(today, datetime.max.time())
        
        # 查询当日的点赞记录，按文章分组统计点赞数
        daily_likes = Like.objects.filter(
            like_type=0,  # 文章点赞
            create_time__range=[today_start, today_end]
        ).values('object_id').annotate(
            daily_like_count=Count('like_id')
        ).order_by('-daily_like_count')
        
        # 获取当日有点赞的文章ID
        daily_article_ids = [item['object_id'] for item in daily_likes]
        
        if len(daily_article_ids) >= 5:
            # 如果当日有点赞的文章数量>=5，直接取前5个
            top_article_ids = daily_article_ids[:5]
            articles = Article.objects.filter(
                article_id__in=top_article_ids
            ).extra(
                select={
                    'daily_like_count': '''
                        SELECT COUNT(*) FROM likes 
                        WHERE likes.object_id = articles.article_id 
                        AND likes.like_type = 0 
                        AND likes.create_time >= %s 
                        AND likes.create_time <= %s
                    '''
                },
                select_params=[today_start, today_end]
            ).order_by('-daily_like_count', '-good_count')
            
        else:
            # 如果当日有点赞的文章数量<5，需要补充其他文章
            # 先获取当日有点赞的文章
            daily_articles = Article.objects.filter(
                article_id__in=daily_article_ids
            ).extra(
                select={
                    'daily_like_count': '''
                        SELECT COUNT(*) FROM likes 
                        WHERE likes.object_id = articles.article_id 
                        AND likes.like_type = 0 
                        AND likes.create_time >= %s 
                        AND likes.create_time <= %s
                    '''
                },
                select_params=[today_start, today_end]
            ).order_by('-daily_like_count', '-good_count')
            
            # 再获取其他文章（按总点赞数排序，排除已有的文章）
            remaining_count = 5 - len(daily_article_ids)
            other_articles = Article.objects.exclude(
                article_id__in=daily_article_ids
            ).order_by('-good_count')[:remaining_count]
            
            # 合并文章列表
            articles = list(daily_articles) + list(other_articles)
        
        # 构建返回数据
        article_list = []
        for article in articles:
            # 计算当日点赞数
            if hasattr(article, 'daily_like_count'):
                daily_count = getattr(article, 'daily_like_count', 0)
            else:
                # 对于补充的文章，需要单独查询当日点赞数
                daily_count = Like.objects.filter(
                    object_id=article.article_id,
                    like_type=0,
                    create_time__range=[today_start, today_end]
                ).count()
            
            article_list.append({
                'articleId': article.article_id,
                'title': article.title,
                'dailyLikeCount': daily_count,
                'totalLikeCount': article.good_count
            })
        
        return success_response({
            'list': article_list
        })
        
    except Exception as e:
        logger.error(f"Failed to get daily top articles: {e}")
        return error_response("Failed to obtain daily top articles, please try again")